package service

// service.go
// 对 User 进行的操作

import (
	"gforum/global"
	"gforum/model"
	"gorm.io/gorm"
)

// GetUser 根据 username 从数据库中读取一整个 User instance
func GetUser(username string) (*model.User, error) {
	var user model.User
	err := global.Db.Where("username = ?", username).First(&user).Error
	if err != nil {
		return nil, err
	}

	return &user, nil
}

// UpdateInfo 将用户信息更新到数据库, 只有有权限的用户能够上传头像，并返回更新后完整的用户信息
func UpdateInfo(userInfo model.UserInfo, username string) (*model.UserInfo, error) {
	updates := userInfoToMap(userInfo)

	if len(updates) == 0 {
		return nil, ErrLackOfInput
	}

	// 有权限的用户才能更新头像，没有权限的用户只能更新其他信息
	var result *gorm.DB
	if _, ok := updates["avatar"]; ok {
		result = global.Db.Model(&model.User{}).Where("username = ? AND level >= 3", username).Updates(updates)
		if result.RowsAffected == 0 {
			return nil, ErrUnAuthorized
		}
	} else {
		result = global.Db.Model(&model.User{}).Where("username = ?", username).Updates(updates)
		if result.RowsAffected == 0 {
			return nil, ErrRecordNotFound
		}
	}
	if result.Error != nil {
		return nil, result.Error
	}

	var updatedUser model.User
	err := global.Db.Where("username = ?", username).First(&updatedUser).Error
	if err != nil {
		return nil, err
	}

	return &updatedUser.UserInfo, nil
}

func userInfoToMap(userInfo model.UserInfo) map[string]any {
	updates := map[string]any{}

	if userInfo.Avatar != "" {
		updates["avatar"] = userInfo.Avatar
	}
	if userInfo.Birthday != "" {
		updates["birthday"] = userInfo.Birthday
	}
	if userInfo.Gender != "" {
		updates["gender"] = userInfo.Gender
	}
	if userInfo.Signature != "" {
		updates["signature"] = userInfo.Signature
	}

	return updates
}

func GetUserInfoByID(id string) (*model.UserInfo, error) {
	var user model.User

	err := global.Db.Where("id = ?", id).First(&user).Error
	if err != nil {
		return nil, err
	}

	return &user.UserInfo, nil
}

func GetUserLevelByID(id string) (*model.UserLevel, error) {
	var user model.User

	err := global.Db.Where("id = ?", id).First(&user).Error
	if err != nil {
		return nil, err
	}

	return &user.UserLevel, nil
}
